var FG;
if (!FG)
    FG = {};


FG.WIDGET_DATASET_TEMPLATE = _.template(
    '<option value="<%= name %>" title="<%= desc %>" type="<%= dstype %>"><%= zh_name %></option>'
);

FG.WIDGET_SUBSET_TEMPLATE = _.template(
    '<li><a href="#"><%= zhName %></a>' +
    '<ul class="varlist">' +
    '</ul>' +
    '</li>'
);

FG.WIDGET_VAR_TEMPLATE = _.template(
    '<li class="var"><%= zhName %></li>'
);

FG.WIDGET_DOWNLOAD_ITEM_TEMPLATE = _.template(
    '<div class="download_item">' +
    '<div><%= name %></div>' +
    '</div>'
);

FG.DSV_TEXTTHUMB_TEMPLATE = _.template(
    '<div class="ttblock itemtype_icon icon_<%= widgetType %>"></div>' +
    '<div class="ttblock dataset icon_<%= dataset %>" title="<%= zhDataset %>"><span><%= zhDataset %></span></div>' +
    '<div class="ttblock subset icon_<%= subset %>" title="<%= zhSubset %>"><span><%= zhSubset %></span></div>' +
    '<div class="ttblock varname icon_<%= varname %>"><span><%= zhVarname %></span></div>' +
    '<div class="ttblock version"><span><%= version %></span></div>' +
    '<div class="ttblock level"><span><%= level %></span></div>' +
    '<div class="ttblock time"><span><%= time %></span></div>'
);

FG.DSV_TEXTTHUMB_DEFAULTS = {
    widget_type: 'point',
    dataset: '',
    subset: '',
    varname: '',
    version: '',
    level: '',
    time: ''
};

FG.SVView = function(opts) {
    // TODO
    var this_ = this;
    
    var defaultOpts = {
        subsetUL: '<ul class="subset_list"></ul>',
        subsetLiTemp: _.template(
            '<li class="subset_tab subset_<%= name %>">' +
            '<a class="head"><%= name %></a>' +
            '<div class="body nano">' +
            '<ul class="var_list nano-content"></ul>' +
            '</div>' +
            '</li>'
        ),
        varLiTemp: _.template('<li class="var var_<%= name %>"><%= name %></li>'),
        toolunitButtonLiTemp: _.template(
            '<li class="toolunit_button toolunit_button_<%= name %>" title="<%= desc %>">' +
            '<%= zhName %>' +
            '</li>'
        ),
        toolunitLabelLiTemp: _.template(
            '<li class="toolunit_label toolunit_label_<%= name %>" title="<%= desc %>">' +
            '<%= zhName %>' +
            '</li>'
        ),
        toolunitInputLiTemp: _.template(
            '<li class="toolunit_input toolunit_input_<%= name %>" title="<%= desc %>">' +
            '<span class="label"><%= zhName %></span>' +
            '<input type="text" name="<%= name %>" placeholder="<%= placeholder %>" value="<%= value %>">' +
            '</li>'
        ),
        toolunitLatlonLiTemp: _.template(
            '<li class="toolunit_lonlat toolunit_lonlat_<%= name %>" title="<%= desc %>">' +
            '<span class="label"><%= zhName %></span>' +
            '<input type="text" name="lat" placeholder="纬度" value="<%= value[0] %>">' +
            '<input type="text" name="lon" placeholder="经度" value="<%= value[1] %>">' +
            '</li>'
        ),
        toolunitSelectLiTemp: _.template(
            '<li class="toolunit_select toolunit_select_<%= name %>" title="<%= desc %>">' +
            '<span> class="label"><%= zhName %></span>' +
            '<select>' +
            '</select>' +
            '</li>'
        ),
        toolunitTableLiTemp: _.template(
            '<li class="toolunit_table toolunit_table_<%= name %>" title="<%= desc %>">' +
            '<div id="toolunit_table_div_<%= name %>"></div>' +
            '</li>'
        )
    };
    
    this.opts = _.extend(defaultOpts, opts);
    this.$target = (this.opts.target instanceof jQuery)? this.opts.target : $(this.opts.target);
    // 父元素的高度
    this.height = this.$target.height();
    this.expandHeight = 0;
    this.subsetToggler = new DX.Toggler({}, {
        bindEvents: ['click'],
        actions: {
            _all: function(next, nextKey, prev, prevKey) {
                if (!!next)
                    next.children('.body').height(this_.expandHeight).show().nanoScroller();
                if (!!prev && prevKey !== nextKey)
                    prev.children('.body').height(0).hide();
            }
        }
    });
    this.svToggler = new DX.Toggler({}, {});
    
    this.$subsetLis = {};
    this.$varLis = {};
    
    this.resizeSensor = new ResizeSensor(this.$target, function() {
        this_.onResize();
    });
    
    /*
     ** 清空所有内容
     */
    this.clear = function() {
        this.$target.empty();
        this.expandHeight = 0;
        this.dataset = null;
        this.svToggler.removeEntry('_all');
        this.subsetToggler.removeEntry('_all');
    };
    
    this.loadData = function(data) {
        this.clear();
        
        var afterLoaded = [];
        var subsetDict = {},
            varnameDict = {};
        if (data.arch === 'dataset') {
            this.dataset = data;
            subsetDict = _.extend({}, data.subset_dict);
            varnameDict = _.extend({}, data.varname_dict);
        }
        var subsets = data.subs;
        
        var $subsetLi, $varUL, $varLi, dsvTag;
        this.$subsetUL = $(this.opts.subsetUL);
        _.each(subsets, function(subset) {
            subset.zhName = subset.zhName || subsetDict[subset.name] || subset.name;
            $subsetLi = $(this_.opts.subsetLiTemp(subset));
            $varUL = $subsetLi.find('.var_list');
            _.each(subset.subs, function(unit) {
                unit.zhName = unit.zhName || varnameDict[unit.name] || unit.name;
                if (data.arch === 'dataset') {
                    $varLi = $(this_.opts.varLiTemp(unit));
                } else if (data.arch === 'toolpanel') {
                    switch(unit.type) {
                        case 'button':
                            $varLi = $(this_.opts.toolunitButtonLiTemp(unit));
                            if (_.has(unit, 'event')) {
                                $varLi.click(function(e) {
                                    e.stopPropagation();
                                    DX.shout(unit.event, unit.event_value);
                                })
                            }
                            break;
                        case 'label':
                            $varLi = $(this_.opts.toolunitLabelLiTemp(unit));
                            break;
                        case 'input':
                            $varLi = $(this_.opts.toolunitInputLiTemp(unit));
                            break;
                        case 'latlon':
                            $varLi = $(this_.opts.toolunitLatlonLiTemp(unit));
                            break;
                        case 'select':
                            $varLi = $(this_.opts.toolunitSelectLiTemp(unit));
                            // TODO add options
                            break;
                        case 'table':
                            $varLi = $(this_.opts.toolunitTableLiTemp(unit));
                            var editableGrid = new EditableGrid(unit.name);
                            editableGrid.tableLoaded = function() {this.renderGrid("toolunit_table_div_" + unit.name);};
                            
                            var jsonData = {
                                metadata: unit.meta,
                                data: unit.value
                            };
                            editableGrid.processJSON(jsonData);
                            afterLoaded.push(function() {
                                editableGrid.renderGrid("toolunit_table_div_" + unit.name);
                            });
                            break;
                        default:
                            $varLi = $('<li></li>')
                    }
                }
                $varUL.append($varLi);
                
                if (data.arch === 'dataset') {
                    dsvTag = [data.name, subset.name, unit.name].join('/');
                    this_.svToggler.pushEntry(dsvTag, $varLi);
                }
            });
            $subsetLi.children('.body').hide();
            this_.$subsetUL.append($subsetLi);
            this_.subsetToggler.pushEntry(subset.name, $subsetLi);
        });
        this.$target.append(this.$subsetUL);
        _.each(afterLoaded, function(f) {
            f();
        });
        this.subsetToggler.toggle(subsets[0].name);
        this.onResize();
    };
    
    this.getDSV = function() {
        var dsvTag = this.svToggler.value();
        if (!!dsvTag) {
            var d_s_v = dsvTag.split('/');
            return {
                dataset: d_s_v[0],
                subset: d_s_v[1],
                variable: d_s_v[2]
            }
        } else {
            return null
        }
    };
    
    this.toggleSV = function(subsetName, varName) {
        this.subsetToggler.toggle(subsetName);
        this.svToggler.toggle(this.dataset.name+'/'+subsetName+'/'+varName);
    };
    
    this.onResize = function() {
        var targetHeight = this.$target.height();
        if (targetHeight !== 0) {
            this.height = targetHeight;
        }
        if (this.subsetToggler.entryOrder.length === 0) {
            this.expandHeight = 0;
        } else {
            var headTotalHeight = 0;
            _.each(this.subsetToggler.entries, function (entry) {
                headTotalHeight += entry.children('.head').outerHeight(true);
            });
            this.expandHeight = this.height - headTotalHeight;
            var currentSubsetKey = this.subsetToggler.value();
            if (!!currentSubsetKey) {
                this.subsetToggler.entries[currentSubsetKey].children('.body').css('height', this.expandHeight).nanoScroller();
            }
        }
    }
};

FG.DownloadBoxView = Backbone.View.extend({
    template: _.template(
        '<div class="head">' +
        '<div class="label">下载</div>' +
        '<div class="dsv"><b>变量: </b><%= dataset %>/<%= subset %>/<%= name %></div>' +
        '<div class="coords"><b>下标: </b><%= coords %></div>' +
        //'<div class="uri"><%= uri %></div' +
        //'<div class="button buy"></div>' +
        '</div>' +
        '<div class="itemlist"></div>'
    ),
    
    itemTemplate: _.template('<a target="_blank" href="<%= link %>"><div class="item format_<%= format %>" format="<%= format %>" title="<%= desc %>"><span><%= showFormat %></span></div></a>'),
    
    formatDescDict: {
        'json': 'JSON: 一种轻量级的数据交换语言, 参考帮助中的数据格式说明',
        'wws': 'WindSim文件格式',
        'csv': 'CSV: 逗号分隔值格式, 可用于Excel',
        'kmz': '谷歌地球图层文件',
        '图片': '图片'
    },
    
    render: function() {
        var this_ = this;
        if (!!this.variable) {
            this.coordsUri = this.variable.coorder.getCombinedReplacedUri();
            var fullUri = [this.variable.uri, this.coordsUri].join('/');
            var subset_dict = this.variable.datasetObj.subset_dict,
                varname_dict = this.variable.datasetObj.varname_dict;
            var contents = {
                dataset: this.variable.datasetObj.zh_name || this.variable.dataset,
                subset: (subset_dict && subset_dict[this.variable.subset]) || this.variable.subset,
                name: (varname_dict && varname_dict[this.variable.name]) || this.variable.name,
                coords: this.coordsUri,
                uri: fullUri
            };
            this.$el.html(this.template(contents));
            var $itemlist = this.$el.children('.itemlist');
            if (!!this.variable.formats) {
                _.each(this.variable.formats, function(format) {
                    var link;
                    var ry_formats = ['rect_figure', 'kmz'];
                    if (_.contains(ry_formats, format)) {
                        var pitem =  this_.model.get('uuid'),
                            lon1 = this_.model.get('lon1'),
                            lat1 = this_.model.get('lat1'),
                            lon2 = this_.model.get('lon2'),
                            lat2 = this_.model.get('lat2'),
                            vrange = this_.widget.vrangeToggler.value();
                        var projection,
                            showFormat;
                        if (format === 'rect_figure') {
                            projection = 'merc';
                            showFormat = '图片';
                        }
                        else if (format === 'kmz') {
                            projection = 'cyl';
                            showFormat = format;
                        }
                        this_.figureInfo = this_.variable.getDataBundle().getData();
                        this_.figureInfo.done(function(itemlist) {
                            var origData = itemlist[0].data;
                            var cmap = FG.getProperCmap(origData.data.suggest_cmap);
                            var vranged = {
                                    'fix': origData.data.fix_range,
                                    'fit': origData.data.fit_range
                                },
                                vmin = vranged[vrange][0],
                                vmax = vranged[vrange][1];
                            // figure template
                            var figure_temp = origData.data.url_para;
                            var figUrlTemplate = _.template([fullUri, figure_temp].join('?'));
                            var figUrl = figUrlTemplate({
                                'format': format,
                                'pitem': pitem,
                                'lon1': lon1,
                                'lat1': lat1,
                                'lon2': lon2,
                                'lat2': lat2,
                                'vmin': vmin,
                                'vmax': vmax,
                                'cmap': cmap,
                                'projection': projection
                            });
                            link = '/data/' + figUrl;
                            $itemlist.append(this_.itemTemplate({format: format, showFormat: showFormat, link: link, desc: this_.formatDescDict[showFormat]}));
                        });
                    }
                    else if (format === 'hc_figure') {
                        var $fc_button = $('<a><div class="item format_hc_figure" format="hc_figure" title="图片"><span>图片</span></div></a>');
                        $itemlist.append($fc_button);
                        var logo = 'http://windgrid.dxwind.com/static/logo/dxwind.png';
                        $fc_button.click(function() {
                            var chart = this_.widget.$figure.highcharts();
                            chart.exportChart({
                                scale: 1.5,
                                // 文件名中含有‘,’字符，导致chrome无法下载图片，firefox可以，因此替换为‘+’字符
                                filename: fullUri.replace(/,/g, "+"),
                                formAttributes: {
                                    target: '_blank'
                                },
                                //type: 'image/svg+xml'
                                type: 'image/png'
                            }, {
                                // chartOptions
                                chart: {
                                    events: {
                                        // load事件
                                        load: function(e) {
                                            this.renderer.image(logo, 500, 0, 90, 35).add();
                                        }
                                    }
                                },
                                legend: {
                                    enabled: true
                                }
                            });
                        });
                    }
                    else {
                        link = '/data/' + fullUri + '?format=' + format + '&ignore_cache=True';
                        $itemlist.append(this_.itemTemplate({format: format, showFormat: format, link: link, desc: this_.formatDescDict[format]}));
                    }
                });
            }
        }
        return this;
    },
    
    events: {
    }
});

FG.EditBoxView = Backbone.View.extend({
    template: _.template(
        '<div class="item_edit_wrapper input_wrapper">' +
        '<textarea class="item_edit input" placeholder="请输入工程条目的描述"></textarea>' +
        '</div>' +
        '<div class="button_row">' +
        '<div class="button item_edit_submit" style="float:right" title="保存"><i class="fa fa-check"></i></div>' +
        '<div class="button item_edit_cancel" style="float:right" title="取消"><i class="fa fa-undo"></i></div>' +
        '</div>'
    ),
    
    render: function() {
        var this_ = this;
        this.$el.html(this.template({}));
        this.$el.find('.item_edit').val(this.model.get('desc'));
        return this;
    },
    
    events: {
        'click .item_edit_submit': function(e) {
            this.model.set('desc', this.$el.find('.item_edit').val());
            this.model.save();
        },
        'click .item_edit_cancel': function(e) {
            this.render();
        }
    }
});

FG.SnapshotBoxView = Backbone.View.extend({
    template: _.template(
        '<div class="snapshot_pane_wrapper nano">' +
        '<div class="hint">如果需要在此处保存所浏览的图表的快照, 请退出当前状态, 并点击右上角的 <i class="fa fa-camera"></i> 按钮, 拍摄得到快照后再回到此处查看. </div>' +
        '<ul class="snapshot_pane nano-content"></ul>' +
        '</div>'
    ),
    
    render: function() {
        var this_ = this;
        this.$el.html(this.template({}));
        var uuid = this.model.get('uuid');
        var snapshots = $('.project_item[uuid="' + uuid + '"]').find('.snapshot_list').children().clone(true);
        var this_list = this.$el.find('.snapshot_pane');
        var this_nano = this.$el.find('.nano');
        snapshots.appendTo(this_list);
        snapshots.find('.ttblock.varname').textfill({maxFontPixels: 16});
        this_list.children().first().remove();
        this_list.children().on("click", ".close", function() {
            $(this).parent().remove();
            this_nano.nanoScroller();
        });
        var hint = this.$el.find('.hint');
        if (this_list.children().length === 0) {
            hint.show();
        } else {
            hint.hide();
        }
        this_nano.nanoScroller();
        return this;
    },
    
    events: {
    }
});

FG.BuyBoxView = Backbone.View.extend({
    template: _.template(
        '<div class="head">' +
        '<div class="label">购买</div>' +
        '<div class="dsv"><b>变量: </b><%= dataset %>/<%= subset %>/<%= name %></div>' +
        '<div class="coords"><b>下标: </b><%= coords %></div>' +
        //'<div class="uri"><%= uri %></div' +
        //'<div class="button buy"></div>' +
        '</div>' +
        '<div class="itemlist">' +
        '<div class="label price_label">价格: ￥ <span class="price_value">?</span></div>' +
        '<div class="item button actual_buy" uri="<%= uri %>"><span>购买</span></div>' +
        '</div>'
    ),
    
    render: function() {
        var this_ = this;
        if (!!this.variable) {
            this.coordsUri = this.variable.coorder.getReplacedUris().join('/');
            var fullUri = [this.variable.uri, this.coordsUri].join('/');
            var subset_dict = this.variable.datasetObj.subset_dict,
                varname_dict = this.variable.datasetObj.varname_dict;
            var contents = {
                dataset: this.variable.datasetObj.zh_name || this.variable.dataset,
                subset: (subset_dict && subset_dict[this.variable.subset]) || this.variable.subset,
                name: (varname_dict && varname_dict[this.variable.name]) || this.variable.name,
                coords: this.coordsUri,
                uri: fullUri
            };
            this.$el.html(this.template(contents));
            var $price_value = this.$el.find('span.price_value');
            $.ajax('/price/'+fullUri, {
                dataType: 'json',
                success: function(data) {
                    $price_value.html(data.result);
                }
            })
        }
        return this;
    },
    
    events: {
        'click .actual_buy': function(e) {
            var uri = e.currentTarget.getAttribute('uri');
            DX.confirm("是否确实要购买此数据 ?", function() {
                DX.shout('buy!', uri);
            });
            e.stopPropagation();
        }
    }
});

FG.FeatureDSVWidgetBase = FG.FeatureWidgetBase.extend({
    className: 'DSV_WidgetBase',
    
    renderModel: function(model) {
        this._renderModelBasic(model);
        this._renderTools();
        this._renderDSV();
        
        this.setContent(this.$content[0]);
        this._switchDefaultViewport();
        return this;
    },
    
    _renderTools: function() {
        var this_ = this,
            model = this.model,
            content = this.$content;
        
        _.each([
            'name_edit', 'lonlat_edit',
            'camera', 'delete_this',
            'buy', 'ds', 'download', 'edit', 'snapshots', 'delete_this',   //buttons
            'photo_port',
            'sample_label', // info labels
            'figscreen',  // screens
            'ds_box', 'buy_box', 'download_box', 'edit_box', 'snapshot_box'  // toolboxes
        ], function(elem) {
            this_['$'+elem] = content.find('.'+elem);
        });
        // 右侧的工具框们
        this.toolboxes = {
            buy: this.$buy_box,
            ds: this.$ds_box,
            download: this.$download_box,
            edit: this.$edit_box,
            snapshots: this.$snapshot_box
        };
        //this.toolbox = 'ds';
        
        if (!this.downloadBoxView) {
            this.downloadBoxView = new FG.DownloadBoxView({el: this.$download_box, model: model});
            this.downloadBoxView.widget = this;
        } else {
            this.downloadBoxView.model = model;
        }
        if (!this.buyBoxView) {
            this.buyBoxView = new FG.BuyBoxView({el: this.$buy_box, model: model});
        } else {
            this.buyBoxView.model = model;
        }
        if (!this.editBoxView) {
            this.editBoxView = new FG.EditBoxView({el: this.$edit_box, model: model});
        } else {
            this.editBoxView.model = model;
        }
        if (!this.snapshotBoxView) {
            this.snapshotBoxView = new FG.SnapshotBoxView({el: this.$snapshot_box, model: model});
        } else {
            this.snapshotBoxView.model = model;
        }
        
        // 照相机按钮
        this.$camera.unbind('click').click(function() {
            this_.genSnapshot();
            // 动画效果
            var uuid = model.get('uuid');
            var snapshot = $('.project_item[uuid="' + uuid + '"]').children('.thumbshot').children('.snapshot').clone();
            this_.$photo_port.empty();
            snapshot.appendTo(this_.$photo_port);
            this_.$photo_port.show();
            snapshot.animate({top: this_.$photo_port.css('height')}, 1000, 'swing', function(){
                this_.$photo_port.hide();
            });
            //this_.$photo_port.hide();
        });
        
        // 改名字
        this.$name_edit.unbind().pressEnter(function() {
            DX.print('name change');
            model.set('name', this_.$name_edit.val());
            model.save();
        });
        
        if (!this.bigButtonToggler) {
            this.bigButtonToggler = new DX.Toggler({
                "camera": this.$camera,
                "delete_this": this.$delete_this
            }, {
                'default': 'camera',
                'activeClass': 'ontop'
            });
        }
        
        if (!this.toolboxToggler) {
            this.toolboxToggler = new DX.Toggler({
                "ds": this.$ds,
                "buy": this.$buy,
                "download": this.$download,
                "edit": this.$edit,
                "snapshots": this.$snapshots
            }, {
                'default': 'ds',
                bindEvents: ['click'],
                onoff: true,
                onoffDefault: true,
                actions: {
                    '_all': function(next, nextKey, prev, prevKey) {
                        if (!!nextKey)
                            this_.toolboxes[nextKey].css('z-index', 999).show();
                        if (!!prevKey && prevKey !== nextKey)
                            this_.toolboxes[prevKey].css('z-index', 0).hide();
                        if (nextKey === 'buy') {
                            this_.buyBoxView.render();
                        }
                
                        if (nextKey === 'snapshots') {
                            this_.bigButtonToggler.toggle('delete_this');
                            this_.snapshotBoxView.render();
                        } else {
                            this_.bigButtonToggler.toggle('camera');
                        }
                
                        if (nextKey === 'edit') {
                            this_.$edit_box.find('.item_edit.input').focus();
                        }
                    }
                }
            });
        }
        
        // 删除本点按钮(删除工具框内)
        this.$delete_this.unbind('click').click(function() {
            DX.confirm('确定要删除此条目吗?', function() {
                DX.shout('pitem:del!', model);
            });
        });
    },
    
    _renderDSV: function() {
        var this_ = this,
            model = this.model,
            content = this.$content;
        
        _.each([
            'dataset', 'subset'
        ], function(elem) {
            this_['$'+elem] = content.find('.ds_box').find('.'+elem);
        });
        
        if (!this.svView) {
            this.svView = new FG.SVView({
                target: this.$subset,
                subsetLiTemp: _.template(
                    '<li class="subset_tab subset_<%= name %>">' +
                    '<a class="head"><%= zhName %></a>' +
                    '<div class="body nano">' +
                    '<ul class="var_list nano-content"></ul>' +
                    '</div>' +
                    '</li>'
                ),
                varLiTemp: _.template('<li class="var var_<%= name %>"><%= zhName %></li>')
            });
        }
        
        this_.$dataset.empty();
        if (_.has(model, 'dsvList') && !_.isEmpty(model.dsvList)) {
            _.each(model.dsvList, function(ds) {
                var data = {dstype: "normal"};
                _.extend(data, ds);
                var $dsItem = $(FG.WIDGET_DATASET_TEMPLATE(data));
                this_.$dataset.append($dsItem);
            });
        }
        
        //关联事件等逻辑
        
        // 数据集选择
        this.$dataset.unbind('change').change(function(e) {
            DX.warn('Changed!: '+this_.$dataset.val());
            var dsName = this_.$dataset.val();
            if (!_.isNull(dsName)) {
                this_.switchDataset(this_.$dataset.val());
            }
        });
        
        
        // 自动触发某些事件, TODO: 检查是否需要挪到setContent之后.
        this.$dataset.trigger('change');
    
        // this_.svView.onResize();
        
        // this.once('open', function() {
        //     this_.svView.onResize();
        // });


        return this;
    },
    
    // 切换工具框
    toggleTool: function(target) {
        // TODO: prevent invalid target
        _.each(this.toolboxes, function(box, key){
            if (key === target) {
                box.css("z-index", "999");
            } else {
                box.css("z-index", "0");
            }
        });
        this.toolbox = target;
        return this;
    },
    
    // 切换数据集
    switchDataset: function(dataset) {
        var this_ = this;
        
        if (_.isString(dataset)) {
            dataset = _.find(this.model.dsvList, function(ds) {
                return ds.name === dataset;
            });
            if (typeof dataset === 'undefined') {
                return;
            }
        }
        //if (!!this.currentDatasetName && (this.currentDatasetName === dsName)) {
        //    DX.print("Not changing Dataset")
        //    return dataset;
        //}
        if (dataset.arch === 'dataset') {
            this.currentDatasetName = dataset.name;
        } else {
            this.currentDatasetName = null;
        }
        
        // this.$subset.empty();
        
        var subsetDict = _.extend({}, dataset.subset_dict);
        var varnameDict = _.extend({}, dataset.varname_dict);
        
        this.svView.loadData(dataset);
        if (dataset.arch === 'dataset') {
            _.each(this.svView.svToggler.entries, function(varEl, dsvTag) {
                varEl.unbind('click').click(function(e) {
                    this_.svView.svToggler.toggle(dsvTag);
                    if (!!dsvTag && dsvTag !== 'none') {
                        var d_s_v = dsvTag.split('/');
                        this_.switchViewport({
                            type: 'SV',
                            status: {
                                pitem: this_.model.get('uuid'),
                                coords: {
                                    dataset: d_s_v[0],
                                    subset: d_s_v[1],
                                    varname: d_s_v[2]
                                },
                                parameters: {}
                            }
                        });
                    }
                })
            });
        }
        
        if (!!dataset.coords) {
            if (!this.globalCoorder) {
                this.globalCoorder = new DX.Coorder();
            }
            this.globalCoorder.clearAll();
            
            _.each(dataset.coords, function(coord) {
                this_.globalCoorder.addCoord(new DX.Coord(coord));
            });
            this.coorderView.switchCoorder(this_.globalCoorder);
        }
        
        this.$dataset.val(dataset.name);
        
        return dataset;
    },
    
    switchSV: function(subset, varname) {
        // TODO: highlight S, V,
        // get V's data,
        var this_ = this;
        
        dsvTag = [this.currentDatasetName, subset, varname].join('/');
        var variable = this.model.variableDict[dsvTag];
        if (!variable) {
            return
        }
        this.currentVariable = variable;
        this.svView.toggleSV(subset, varname);
        
        this.coorderView.switchCoorder(variable.coorder);
        // 重新绑定 坐标按钮的事件.
        var coorder = variable.coorder;
        var databundle = variable.getDataBundle();
        
        coorder.off().on('coord_change', function(model, coord, value) {
            DX.error(coord.get('name') + ':' + String(value));
            if (_.isEmpty(value)) {
                return;
            }
            databundle = variable.getDataBundle();
            var coords = {
                dataset: this_.currentDatasetName,
                subset: subset,
                varname: varname
            };
            coords[coord.get('name')] = value;
            this_.switchViewport({
                type: 'coorder',
                status: {
                    pitem: this_.model.get('uuid'),
                    coords: coords,
                    parameters: {}
                }
            });
        });
        return variable;
    },
    
    switchViewport: function(viewport) {
        var this_ = this;
        DX.warn(viewport);
        var variable;
        var parameters;
        if (viewport.type === "refresh") {
            variable = this.currentVariable;
        } else {
            
            var newStatus = viewport.status;
            if (_.isEmpty(newStatus))
                return;
            if (!(viewport.type === 'coorder' || viewport.type === 'SV')) {
                var dataset = this.switchDataset(newStatus.coords.dataset);
                if (!dataset) {
                    return;
                } else {
                    this.currentDatasetName = newStatus.coords.dataset;
                }
            }
            if (viewport.type !== 'coorder') {
                variable = this.switchSV(newStatus.coords.subset, newStatus.coords.varname, viewport.opts);
                this.currentVariable = variable;
            } else {
                variable = this.currentVariable;
            }
            if (!variable) {
                return;
            }
            var restCoords = _.omit(newStatus.coords, 'dataset', 'subset', 'varname');
            variable.coorder.setMultipleCoordSelects(restCoords);
        }
        
        // 安排下载按钮
        this.downloadBoxView.setElement(this.$download_box);
        this.downloadBoxView.variable = variable;
        this.downloadBoxView.render();
        
        this.buyBoxView.setElement(this.$buy_box);
        this.buyBoxView.variable = variable;
        //this.buyBoxView.render();  // 为了减少不必要的price接口调用, 下载页面只在用户切换到此界面时才渲染.
        
        this.editBoxView.render();
        
        // 取数据画图
        this.plotFigure(variable, parameters, undefined, function(itemlist) {
            // TODO: 目前由于每次只展示一个dataunit, 所以itemlist总是长度为1.
            this_.genSnapshot({uuid: this_.model.get('uuid'), update: true});
            if (!!itemlist && itemlist.length > 0) {
                this_.toggleSample(itemlist[0].data.info['sample'])
            }
        });
    },
    
    _switchDefaultViewport: function() {
        var model = this.model;
        if (_.has(model, 'snapshotList') && model.snapshotList.length > 0) {
            var ss = model.snapshotList.at(0);
            var viewport = _.extend({type: "snapshot"}, ss.attributes);
            this.switchViewport(viewport);
        }
        return this;
    },
    
    toggleSample: function(status) {
        if (!!status) {
            this.$sample_label.removeClass('inactive');
            this.$buy.removeClass('inactive');
        } else {
            this.$sample_label.addClass('inactive');
            this.$buy.addClass('inactive');
            if (this.toolboxToggler.value() === 'buy') {
                this.toolboxToggler.toggle('ds');
            }
        }
    },
    
    plotFigure: function(variable, parameters, target, callback) {
        var dataBundle = variable.getDataBundle();
        var this_ = this;
        
        target = !!target ? target : this.$figure;
        // TODO
        if (!_.isUndefined(target.highcharts)) {
            var oldChart = target.highcharts();
            if (!_.isUndefined(oldChart)) {
                oldChart.destroy();
            }
        }
        target.empty();
        this.showLoading();
        this.hideHint();
        // TODO: 需要改为生成FigPane或Combo(最好是Combo, 哪怕是只有一个Pane)
        var pane = new FG.FigPane({type: 'datatype', databundle: dataBundle, parameters: parameters});
        //DX.print(pane)
        //var combo = FG.getSingleCombo(pane);
        pane.render(target, function() {
            callback.apply(this, arguments);
            this_.hideLoading();
        });
    },
    
    genSnapshot: function(opts) {
        var this_ = this,
            model = this.model;
        var opts = _.extend({}, opts);
        
        var coords = this_.currentVariable.coorder.getAllCoordsSelects({ignoreDependCoords: true});
        var varname_dict = this_.currentVariable.datasetObj.varname_dict;
        var subset_dict = this_.currentVariable.datasetObj.subset_dict;
        _.extend(coords, {
            dataset: this_.currentVariable.dataset,
            subset: this_.currentVariable.subset,
            varname: this_.currentVariable.name
        });
        var extraInfo = {
            zhDataset: this_.currentVariable.datasetObj.zh_name || this_.currentVariable.dataset,
            zhSubset: (subset_dict && subset_dict[this_.currentVariable.subset]) || this_.currentVariable.subset,
            zhVarname: (varname_dict && varname_dict[this_.currentVariable.name]) || this_.currentVariable.name
        };
        
        var status = {
            pitem: model.get('uuid'),
            coords: coords,
            parameters: {}
        };
        var textthumb = this_.genTextThumb(status, extraInfo);
        
        if (_.has(this_._source, 'imageUrl') && this_._source.imageUrl !== ''){
            thumbnail = '/data/' + this_._source.imageUrl;
        } else {
            thumbnail = ''
        }
        var nowStr = moment().format('YY/MM/DD hh:mm');
        if (!!opts.update && !!opts.uuid) {
            DX.shout('snapshot:push!',
                {
                    uuid: opts.uuid,
                    pitem_uuid: model.get('uuid'),
                    pitem: model,
                    html: textthumb,
                    thumbnail: thumbnail,
                    type: '',
                    desc: '',
                    caption: nowStr,
                    status: status
                })
        } else {
            DX.shout('snapshot:push!',
                {
                    uuid: DX.gen_uuid16(),
                    pitem_uuid: model.get('uuid'),
                    pitem: model,
                    html: textthumb,
                    thumbnail: thumbnail,
                    type: '',
                    desc: '',
                    caption: nowStr,
                    status: status
                });
        }
    },
    
    genTextThumb: function(status, extraInfo) {
        var data = _.clone(FG.DSV_TEXTTHUMB_DEFAULTS);
        _.extend(data, status.coords, extraInfo);
        data.widgetType = this.options.widgetType;
        return FG.DSV_TEXTTHUMB_TEMPLATE(data);
    },
    
    showLoading: function() {
        if (_.has(this, '$loading')) {
            this.$loading.show();
        }
    },
    
    hideLoading: function() {
        if (_.has(this, '$loading')) {
            this.$loading.hide();
        }
    },
    
    showHint: function() {
        if (_.has(this, '$hint')) {
            this.$hint.show();
        }
    },
    
    hideHint: function() {
        if (_.has(this, '$hint')) {
            this.$hint.hide();
        }
    }
});

